package com.authine.cloudpivot.ext.controller;


import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.authine.cloudpivot.engine.api.facade.WorkflowInstanceFacade;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.engine.api.model.runtime.*;
import com.authine.cloudpivot.engine.api.model.workflow.WorkflowTemplateHeaderModel;
import com.authine.cloudpivot.engine.component.query.api.Page;
import com.authine.cloudpivot.engine.component.query.api.helper.PageableImpl;
import com.authine.cloudpivot.engine.enums.ErrCode;
import com.authine.cloudpivot.engine.enums.type.DefaultPropertyType;
import com.authine.cloudpivot.engine.enums.type.ProcessRunMode;
import com.authine.cloudpivot.engine.workflow.model.activity.ParticipantActivity;
import com.authine.cloudpivot.ext.task.TaskDelayedManager;
import com.authine.cloudpivot.web.api.controller.runtime.FormRuntimeController;
import com.authine.cloudpivot.web.api.view.ResponseResult;
import com.authine.cloudpivot.web.api.view.bizservice.BizServiceMethodVO;
import com.authine.cloudpivot.web.api.view.runtime.BizObjectVO;
import com.authine.cloudpivot.web.api.view.runtime.FormSaveVO;
import com.authine.cloudpivot.web.api.view.runtime.StartWorkflowDataVO;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Api(description = "二次开放发起流程接口", tags = "二次开放发起流程接口")
@RestController
@RequestMapping("/public/bizrule")
@Slf4j
public class FZVController extends FormRuntimeController {

//    @Autowired
//    private JdbcTemplateAutoConfiguration primaryJdbcTemplate;
    @Autowired
    private HttpServletRequest request;


    /**
     * 自定义流程获取参与者接口
     * @param createUser
     * @return
     */
    @PostMapping("/getUserId")
    public String getUserId(String createUser){
        log.info("getUserId:{}", createUser);
        String createId = getIdFromSelectionValue(createUser);
        log.info("createId:{}", createId);

        if (!StringUtils.isEmpty(createId)){

            return getLeaderId(createId);
        }
        return "";
    }


    /**
     * 发起流程接口
     */
    @GetMapping("/startFlow")
    public ResponseResult<String> startFlow(String SerialNumber,String CustomerName,String userNo, String workflowCode){

        log.info("发起流程参数：userNo:"+userNo+" workflowCode:"+workflowCode);
        StartWorkflowDataVO startWorkflowDataVO = new StartWorkflowDataVO();
        startWorkflowDataVO.setUsername(userNo);
        startWorkflowDataVO.setWorkflowCode(workflowCode);

        Map<String, Object> data = Maps.newHashMap();
//        data.put("RelevanceForm1621559822958",SerialNumber);
//        data.put("ShortText1622096574736",CustomerName);
//        data.put("ShortText1622096574736",CustomerName);
        data.put("RelevanceForm1621559822958",SerialNumber);
        data.put("RelevanceForm1623910145903",CustomerName);
//        data.put("ShortText1624587683188",SerialNumber);
//        data.put("RelevanceForm1624588087614",CustomerName);
        startWorkflowDataVO.setData(data);
        return startWorkflow(startWorkflowDataVO);
    }


    /**
     * 业务集成通用发起流程接口
     */
    @PostMapping("/startFlowUniversal")
    public ResponseResult<String> startFlowUniversal(  @RequestBody Map<String,Object> map){
        String userNo = request.getParameter("userNo");
        String workflowCode = request.getParameter("workflowCode");

        log.info("\n=========通用发起流程参数：userNo:{},\n workflowCode:{},\n 业务数据:{}",userNo,workflowCode,JSON.toJSONString(map));
        StartWorkflowDataVO startWorkflowDataVO = new StartWorkflowDataVO();
        startWorkflowDataVO.setUsername(userNo);
        startWorkflowDataVO.setWorkflowCode(workflowCode);


        startWorkflowDataVO.setData(map);
        return startWorkflow(startWorkflowDataVO);
    }
    private Map<String, Object> getHeadersInfo() {
        Map<String, Object> map = new HashMap<String, Object>();
        Enumeration headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = (String) headerNames.nextElement();
            Object value = request.getHeader(key);
            map.put(key, value);
        }
        return map;
    }


    @PostMapping("/service_test")
    public ResponseResult<Map<String,Object>> testBizServiceMethod(@RequestBody BizServiceMethodVO bizServiceMethodVO) {
        Map<String,Object> map = new HashMap<>();
        map = getBizServiceFacade().testBizServiceMethod(bizServiceMethodVO.getServiceCode(),bizServiceMethodVO.getCode(),bizServiceMethodVO.getTestInputParametersMap());
        return getOkResponseResult(map, "运行业务集成方法成功");
    }



    public String getIdFromSelectionValue(String creteaUser){
        try {
            String[] split = creteaUser.split(",");
            for (String a : split){
                if (a.trim().startsWith("id")){
                    String[] id = a.split("=");
                    return id[1];
                }
            }
        } catch (Exception e) {
            log.error("解析选人控件异常", e);
        }
        return "";
    }

    public String getLeaderId(String userId){
        BizObjectQueryModel queryModel = new BizObjectQueryModel();
        queryModel.setSchemaCode("zhuguanpeizhi");
        queryModel.setQueryCode("zhuguanpeizhi");
        queryModel.setPageable(new PageableImpl(0, 100));
        Page<BizObjectModel> modelPage = getBizObjectFacade().queryBizObjects(queryModel);

        if (modelPage != null && !CollectionUtils.isEmpty(modelPage.getContent())){
            List<? extends BizObjectModel> content = modelPage.getContent();
            if (!CollectionUtils.isEmpty(content)){
                for (BizObjectModel model : content) {
                    ArrayList<SelectionValue> users = (ArrayList<SelectionValue>) model.getData().get("StaffSelector1600399320592");
                    if (!CollectionUtils.isEmpty(users)){
                        for (SelectionValue user : users){
                            String id = user.getId();
                            if (userId.equals(id)){
                                ArrayList<SelectionValue> leaderUser = (ArrayList<SelectionValue>)model.getData().get("StaffSelector1600399280115");
                                if (!CollectionUtils.isEmpty(leaderUser)){
                                    return leaderUser.get(0).getId();
                                }
                            }
                        }

                    }
                }
            }
        }
        return "";
    }

    public ResponseResult<String> startWorkflow(StartWorkflowDataVO bizObject){
        if (bizObject == null) {
            return getErrResponseResult("", ErrCode.SYS_PARAMETER_EMPTY.getErrCode(), "参数为空");
        }
        String workflowCode = bizObject.getWorkflowCode();
        String username = bizObject.getUsername();
        boolean finishStart = bizObject.getFinishStart();
        Map<String, Object> data = bizObject.getData();
        log.info("start workflow: workflowCode = {}, username = {}, formData = {}", workflowCode, username,
                JSON.toJSONString(data));

        UserModel userModel = getOrganizationFacade().getUserByUserNameAndCorpId(username, getMainCorpId());
        if (userModel == null) {
            return getErrResponseResult(username, ErrCode.ORG_USER_NONEXISTENT.getErrCode(), "用户不存在");
        }
        WorkflowTemplateHeaderModel headerModel = getAppManagementFacade().getWorkflowTemplateHeader(workflowCode);
        if (headerModel == null) {
            return getErrResponseResult(workflowCode, ErrCode.WORKFLOW_NOT_EXIST.getErrCode(), "流程不存在");
        }

        ParticipantActivity participantActivity = getAppManagementFacade().getOriginateActivity(workflowCode, null);
        if (participantActivity == null) {
            return getErrResponseResult(workflowCode, ErrCode.WORKFLOW_NO_START_ACTIVITY.getErrCode(), "没有找到流程发起节点");
        }

        BizObjectModel bo = new BizObjectModel(headerModel.getSchemaCode(), data, false);
        bo.setFormCode(participantActivity.getSheetCode());

        String workflowInstanceId = "";
        if (!finishStart) {
            BizObjectVO bov = new BizObjectVO();
            bov.setBizObject(bo);
            bov.setWorkflowCode(workflowCode);

            if (org.apache.commons.lang3.StringUtils.isBlank(bov.getBizObject().getString(DefaultPropertyType.OWNER_DEPT_ID.getCode()))) {
                bov.getBizObject().setOwnerDeptId(userModel.getDepartmentId());
            }

            FormSaveVO resultVO = saveWorkflow(userModel.getId(), userModel.getId(), bov);
            if (resultVO == null) {
                return getErrResponseResult(workflowCode, ErrCode.WORKFLOW_NOT_EXIST.getErrCode(), "流程发起失败1");
            }
            //workflowInstanceId = resultVO.getWorkItem().getInstanceId();
        }
        return getOkResponseResult("ok","");
    }


    private FormSaveVO saveWorkflow(String userId, String ownerId, BizObjectVO bizObjectVO) {
        String workflowCode = bizObjectVO.getWorkflowCode();

        validateNotEmpty(workflowCode, ErrCode.WORKFLOW_CODE_EMPTY.getErrMsg());
        FormSaveVO formSave = new FormSaveVO();
        BizObjectModel objectModel = bizObjectVO.getBizObject();
        String workflowInstanceId = objectModel.getWorkflowInstanceId();

        //objectModel.setFormCode(getFormCode(workflowInstanceId, workflowCode));
        String objectId = objectModel.getId();

        //是否是发起流程
        boolean isStartWf = org.apache.commons.lang3.StringUtils.isEmpty(workflowInstanceId);

        // 发起流程，防止重复提交
        if (isStartWf) {
            objectModel.setWorkflowInstanceId(UUID.randomUUID().toString().replaceAll("-", ""));
            //校验码去掉
            //this.verifyReplay(bizObjectVO.getReplayToken());
        }


        formSave.setObjectId(objectId);
        WorkItemModel workItem;

        if (!isStartWf) {//暂存
            objectId = temporaryStore(userId, bizObjectVO.getWorkItemId(), objectModel, bizObjectVO.getApproval());
            bizObjectVO.setWorkflowInstanceId(workflowInstanceId);
            workItem = getWorkOrCirculateItem(bizObjectVO.getWorkItemId());
        } else {
            // 发起流程
            String departmentId = objectModel.getString(DefaultPropertyType.OWNER_DEPT_ID.getCode());
            workflowInstanceId = startWorkflow(departmentId, userId, null, objectModel, bizObjectVO.getApproval(), workflowCode, Boolean.TRUE, false, ProcessRunMode.MANUAL);
            workItem = getWorkItemByInstanceIdAndUserId(userId, workflowInstanceId);
            formSave.setWorkflowInstanceId(workflowInstanceId);
        }

        if (workItem != null) {
            if (log.isDebugEnabled()) {
                log.debug("workflowCode = {}, instanceId = {},", workflowCode, workflowInstanceId);
            }

            //saveComment(userId, objectId, objectModel.getSchemaCode(), bizObjectVO.getApproval(), FormActionType.TS);

            formSave.setWorkItem(workItem);

            //BizObjectCreatedModel bizObjectCreated = getBizObjectFacade().getBizObject(userId, objectModel.getSchemaCode(), objectId);
            //writeOperationLogForBizObject(workItem.getInstanceId(), workItem.getId(), workItem.getActivityCode(), OperationType.TEMPORARY_STORAGE, bizObjectCreated);
            //writeOperationLog(workItem.getInstanceId(), workItem.getId(), null, OperationType.TEMPORARY_STORAGE, null);
        }
        return formSave;
    }



    public String getUserNameByErp(String userNo){
        BizObjectQueryModel queryModel = new BizObjectQueryModel();
        queryModel.setSchemaCode("erpuser");
        queryModel.setQueryCode("erpuser");
        queryModel.setPageable(new PageableImpl(0, 100));
        Page<BizObjectModel> modelPage = getBizObjectFacade().queryBizObjects(queryModel);

        if (modelPage != null && !CollectionUtils.isEmpty(modelPage.getContent())){
            List<? extends BizObjectModel> content = modelPage.getContent();
            if (!CollectionUtils.isEmpty(content)){
                for (BizObjectModel model : content) {
                    String erpUserNo = (String) model.getData().get("erpUserNo");
                    if (!StringUtils.isEmpty(erpUserNo) && erpUserNo.equals(userNo)){
                        return (String) model.getData().get("userNo");
                    }
                }
            }
        }
        return "";
    }


    @GetMapping("delayPushWorkItem")
    public ResponseResult  delayPushWorkItem(String url,String instanceId,String activityCode,Boolean isFinish){

        log.info("\n============进入测试 ");

        Runnable runnable = () -> {
            try {
                ResponseResult<List> rst = getWorkItemInfo(instanceId, activityCode, false);


                String body = HttpUtil.createPost(url).timeout(10000).body(JSON.toJSONString(rst)).execute().body();


                log.info("============响应结果:{}", body);
            } catch (Exception e) {
                log.info("延时推送待办信息失败..:{}",e);
            }
        };

        TaskDelayedManager.put(runnable,10, TimeUnit.SECONDS);

        return  getOkResponseResult("");
    }


    /**
     *  获取待办信息
     * @param instanceId  流程id,必填
     * @param activityCode  节点code,非必填
     * @param isFinish  true 加载已办, 非必填, 默认加载待办
     * @return
     */
    @GetMapping("getWorkItemInfo")
    public ResponseResult<List>  getWorkItemInfo(String instanceId,String activityCode,Boolean isFinish){

        log.info("\n================getWorkItemInfo,请求参数instanceId={},activityCode={},isFinish={}",instanceId,activityCode,isFinish);

        String itemTemp = "/form/detail?workitemId={}&workflowInstanceId={}";
        WorkflowInstanceFacade wf = getWorkflowInstanceFacade();

        isFinish =  isFinish == null || isFinish==false  ? false : true;

        WorkflowInstanceModel workflowInstance = wf.getWorkflowInstance(instanceId);

        if (workflowInstance == null) {
            log.info("========获取待办信息失败,流程不存在,instanceid ={}",instanceId);
            return getOkResponseResult(Collections.emptyList(),"");
        }

        //getworkItems 描述错的, isFinish true 是查询已办
        List<WorkItemModel> workItems = wf.getWorkItems(instanceId, isFinish);


        if (!StringUtils.isEmpty(activityCode)){
            workItems = workItems.stream().filter(a -> activityCode.equals(activityCode)).collect(Collectors.toList());
        }

        if (workItems.isEmpty()) {
            log.info("========获取待办信息失败,流程id={}",instanceId);
//            return getOkResponseResult(Collections.emptyList(),"");
            return getOkResponseResult(Collections.emptyList(),"");
        }

        List<Map<String, Object>> list = workItems.stream().map(a ->
                MapBuilder.create(new HashMap<String, Object>())
                        .put("url", StrUtil.format(itemTemp, a.getId(), a.getInstanceId()))
                        .put("username", getUsername(a.getParticipant()))
                        .put("activityCode", a.getActivityCode())
                        .put("activityName", a.getActivityName())
                        .put("state", a.getState().name()).build())
                .collect(Collectors.toList());

        return getOkResponseResult(list,"");
    }


    private String getUsername(String id){
        UserModel user =  getOrganizationFacade().getUser(id);
        return Optional.ofNullable(user).orElse(new UserModel()).getUsername();
    }




}
